using System;
using System.Collections.Generic;

namespace dbones.PlugIn
{
    /// <summary>
    /// a loaded plugin
    /// </summary>
    public class ActualPlugIn
    {
        /// <summary>
        /// Creates an instance of a Actual PlugIn
        /// </summary>
        /// <param name="type">the plugin class</param>
        public ActualPlugIn(Type type)
        {
            _observers = new List<IPlugInObserver>();
            Class = type;
            if (type is IPlugInProvider)
            {
                IPlugInProvider provider = (IPlugInProvider)type;
                Name = provider.Name;
                Provider = provider.Provider;
            }
            else
            {
                Name = type.FullName;
            }
        }

        private readonly IList<IPlugInObserver> _observers;
        private bool _default;

        /// <summary>
        /// the plug in
        /// </summary>
        public Type Class { get; set; }

        /// <summary>
        /// the interface the plug in is for
        /// </summary>
        public Type SupportedInterface { get; set; }

        /// <summary>
        /// the name of the plug in
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// the people who provided the plug in
        /// </summary>
        public string Provider { get; set; }

        /// <summary>
        /// Weather or not, this plug in is the detault implementation
        /// </summary>
        public bool IsDefault
        {
            get { return _default; }
            set
            {
                _default = value;
                Notify();
            }
        }

        /// <summary>
        /// Attach an observer
        /// </summary>
        /// <param name="observer"></param>
        public void Attach(IPlugInObserver observer)
        {
            _observers.Add(observer);
        }

        /// <summary>
        /// detach an observer
        /// </summary>
        /// <param name="observer"></param>
        public void Detach(IPlugInObserver observer)
        {
            _observers.Remove(observer);
        }

        /// <summary>
        /// notify any observer on an update
        /// </summary>
        protected void Notify()
        {
            foreach (var observer in _observers)
            {
                observer.Update(this);
            }
        }
    }
}